using english_sentences.Models;
using english_sentences.MongoRepository;
using english_sentences.Services;
using english_sentences.Services.Interface;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;
using Serilog;
using Serilog.Events;
using Microsoft.AspNetCore.SpaServices.AngularCli;

namespace english_sentences
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
             .MinimumLevel.Debug()
             .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
             .Enrich.FromLogContext()
             .WriteTo.Console()
             .WriteTo.File(@"Logs/log.txt",
                 fileSizeLimitBytes: 1_000_000,
                 rollOnFileSizeLimit: true,
                 shared: true,
                 flushToDiskInterval: TimeSpan.FromSeconds(1))
             .CreateLogger();

            try
            {
                Log.Information("Starting web host");
                var allowSpecificOrigins = "_allowSpecificOrigins";

                var builder = WebApplication.CreateBuilder(args);

                builder.Host.UseSerilog(Log.Logger, dispose: true);

                builder.Services.AddIdentity<User, Role>().AddMongoDbStores<User, Role, Guid>
                (
                    builder.Configuration.GetSection("MONGODB_URI").Value, "englishsentences-database"
                );
                if (!builder.Environment.IsDevelopment())
                {
                    builder.Services.Configure<MvcOptions>(options =>
                    {
                        options.Filters.Add<HttpResponseExceptionFilter>();
                    });
                }

                builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
                {
                    options.RequireHttpsMetadata = false;
                    options.SaveToken = true;
                    options.ClaimsIssuer = builder.Configuration["Authentication:JwtIssuer"];
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidIssuer = builder.Configuration["Authentication:JwtIssuer"],
                        ValidateAudience = true,
                        ValidAudience = builder.Configuration["Authentication:JwtAudience"],
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(builder.Configuration["Authentication:JwtKey"])),
                        RequireExpirationTime = true,
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.Zero,

                    };
                });

                builder.Services.AddCors(options =>
                {
                    options.AddPolicy(allowSpecificOrigins,
                                          policy =>
                                          {
                                              policy.WithOrigins("http://localhost","capacitor://localhost", "http://localhost:4200","http://localhost:5088","ws://localhost:5088").AllowAnyHeader().AllowAnyMethod();
                                          });
                });
                builder.Services.AddSpaStaticFiles(configuration =>
                {
                    configuration.RootPath = "ClientApp/dist";
                });

                // Add services to the container.
                builder.Services.AddRazorPages();
                builder.Services.AddControllers();
                // builder.Services.AddEndpointsApiExplorer();
                // builder.Services.AddSwaggerGen();
                builder.Services.AddSingleton<ITranslatorService, TranslatorService>();
                builder.Services.AddSingleton<IVoiceService, VoiceService>();
                builder.Services.AddSingleton<IBlobService, BlobService>();
                builder.Services.AddScoped(typeof(IDataStoreService<,>), typeof(DataStoreService<,>));

                var app = builder.Build();

                IdentityModelEventSource.ShowPII = true; // here
                // Configure the HTTP request pipeline.

                app.UseStaticFiles();
                if (!app.Environment.IsDevelopment())
                {
                    app.UseSpaStaticFiles();
                }
                app.UseRouting();
                app.UseCors(allowSpecificOrigins);
                app.UseAuthentication();
                app.UseAuthorization();
              
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller}/{action=Index}/{id?}");
                });
                // app.MapRazorPages();
                // if (app.Environment.IsDevelopment())
                // {
                //     app.UseSwagger();
                //     app.UseSwaggerUI(options =>
                //     {
                //         options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
                //         options.RoutePrefix = string.Empty;
                //     });
                // }
                 app.UseSpa(spa =>
                {
                    // To learn more about options for serving an Angular SPA from ASP.NET Core,
                    // see https://go.microsoft.com/fwlink/?linkid=864501

                    spa.Options.SourcePath = "ClientApp";

                    if (app.Environment.IsDevelopment())
                    {
                        
                        spa.UseAngularCliServer(npmScript: "start");
                    }
                });

                app.Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly");

            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
    }
}